#include <iostream>
#include <functional>

using std::cout;
using std::endl;
using std::bind;
using std::function;

int add(int x, int y, int z)
{
    cout << "int add(int, int, int)" << endl;
    return x + y + z;
}

class Example
{
public:
    int add(int x, int y)
    {
        cout << "int Example::add(int, int)" << endl;
        return x + y;
    }

    int data = 1000;//C++11提出的特性（将数据成员就地初始化）
};

/* int a = 10; */
/* string s1 = "hello"; */

void test()
{
    //函数也有类型，函数的类型如何确定呢（函数的类型、函数的形态、函数的标签）
    //函数的类型：函数的返回类型 + 函数的参数列表（参数的个数、顺序、类型）
    //add函数int(int, int, int)
    //f的类型应该是int()
    /* auto f = bind(&add, 1, 3, 5); */
    //function存放的是函数的类型，将其称为函数的容器
    //bind可以改变函数的形态(类型、标签):改变了函数的参数个数(减少了)
    function<int()> f = bind(&add, 1, 3, 5);
    cout << "f() = " << f() << endl;

    cout << endl;
    Example ex;
    //f2的类型int()
    function<int()> f2 = bind(&Example::add, &ex, 10, 20);
    cout << "f2() = " << f2() << endl;

    cout << endl;
    function<int()> f3 = bind(&Example::add, ex, 10, 20);
    cout << "f3() = " << f3() << endl;

    cout << endl;
    using namespace std::placeholders;
    //add函数int(int, int, int)
    //f4的类型int(int, int)
    /* auto f4 = bind(&add, 10, _1, _2); */
    function<int(int, int)> f4 = bind(&add, 10, _1, _2);
    cout << "f4(100, 200) = " << f4(100, 200) << endl;

    cout << endl << endl;
    Example ex2;
    function<int()> f5 = bind(&Example::data, &ex2);
    cout << "f5() = " << f5() << endl;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

